#ifndef __SCULL_H__
#define __SCULL_H__

#include <linux/ioctl.h>	/* Needed for the _IOW etc stuff used later. */

/* Macors to help debuging. */
#undef PDEBUG
#ifdef SCULL_DEBUG
	#ifdef __KERNEL__
		/* This one ifdebugging is on, and kernel space */
		#define PDEBUG(fmt, args...)	printk(KERN_DEBUG "scull: [%s] " fmt, __func__, ##args)
	#else
		/* This one for user space*/
		#define PDEBUG(fmt, args...)	fprintf(stderr, fmt, ##args)
	#endif
#else
	/* Not debugging: nothing */
	#define PDEBUG(fmt, args...)	
#endif

#ifndef SCULL_MAJOR
#define SCULL_MAJOR 0
#endif

#ifndef SCULL_NR_DEVS
#define SCULL_NR_DEVS  4
#endif

#define SCULL_P_NR_DEVS 4

#define SCULL_QUANTUM	4000
#define SCULL_QSET		1000

#define SCULL_P_BUFFER	4000

/* Representation of scull quantum sets. */
struct scull_qset{
	void **data;
	struct scull_qset *next;
};

struct scull_dev {
	struct scull_qset *data;	/* Pointer to first quantum set*/
	int quantum;				/* The current quantum size */
	int qset;					/* The current array size*/
	unsigned long size;			/* amount of data stored here. */
	unsigned int access_key;
	struct semaphore sem;
	struct cdev cdev;			/* Char device structure. */
};


extern int scull_p_buffer;
int scull_p_init(dev_t dev);
void scull_p_cleanup(void);

/*
 *  * Ioctl definitions
 *   */

/* Use 'k' as magic number */
#define SCULL_IOC_MAGIC  'k'
/* Please use a different 8-bit number in your code */
#define SCULL_IOCRESET    _IO(SCULL_IOC_MAGIC, 0)

/*
 *  * S means "Set" through a ptr,
 *  * T means "Tell" directly with the argument value
 *  * G means "Get": reply by setting through a pointer
 *  * Q means "Query": response is on the return value
 *  * X means "eXchange": switch G and S atomically
 *  * H means "sHift": switch T and Q atomically
 */
#define SCULL_IOCSQUANTUM _IOW(SCULL_IOC_MAGIC,  1, int)
#define SCULL_IOCSQSET    _IOW(SCULL_IOC_MAGIC,  2, int)
#define SCULL_IOCTQUANTUM _IO(SCULL_IOC_MAGIC,   3)
#define SCULL_IOCTQSET    _IO(SCULL_IOC_MAGIC,   4)
#define SCULL_IOCGQUANTUM _IOR(SCULL_IOC_MAGIC,  5, int)
#define SCULL_IOCGQSET    _IOR(SCULL_IOC_MAGIC,  6, int)
#define SCULL_IOCQQUANTUM _IO(SCULL_IOC_MAGIC,   7)
#define SCULL_IOCQQSET    _IO(SCULL_IOC_MAGIC,   8)
#define SCULL_IOCXQUANTUM _IOWR(SCULL_IOC_MAGIC, 9, int)
#define SCULL_IOCXQSET    _IOWR(SCULL_IOC_MAGIC,10, int)
#define SCULL_IOCHQUANTUM _IO(SCULL_IOC_MAGIC,  11)
#define SCULL_IOCHQSET    _IO(SCULL_IOC_MAGIC,  12)

/*
 *  * The other entities only have "Tell" and "Query", because they're
 *   * not printed in the book, and there's no need to have all six.
 *    * (The previous stuff was only there to show different ways to do it.
 *     */
#define SCULL_P_IOCTSIZE _IO(SCULL_IOC_MAGIC,   13)
#define SCULL_P_IOCQSIZE _IO(SCULL_IOC_MAGIC,   14)
/* ... more to come */

#define SCULL_IOC_MAXNR 14

#endif

